#ifndef RECT_H_
#define RECT_H_

#ifdef __SYMBIAN32__
#include <e32base.h>
#endif

class TRectEx : public TRect
	{
public:
	inline TRectEx();
	inline TRectEx(TInt aAx, TInt aAy, TInt aBx, TInt aBy);
	inline TRectEx(const TPoint& aPointA, const TPoint& aPointB);
	inline TRectEx(const TPoint& aPoint, const TSize& aSize);
	inline TRectEx(const TSize& aSize);
	inline TRectEx(const TRect& aRect);
	inline static TRect FromLTRB(TInt left, TInt top, TInt right, TInt bottom);
	inline static TBool Contains(TInt x, TInt y, TInt left, TInt top, TInt width, TInt height);
	inline static TRect Inflate(const TRect& rect, TInt x, TInt y);
	inline static TRect Intersect(TInt ax, TInt ay, TInt aw, TInt ah, TInt bx, TInt by, TInt bw, TInt bh);
	inline static TRect Intersect(const TRect& a, const TRect& b);
	inline static TBool IntersectsWith(TInt ax, TInt ay, TInt aw, TInt ah, TInt x, TInt y, TInt w, TInt h);
	inline static TRect Union(const TRect& a, const TRect& b);
	inline void Set(const TRect& aRect);
	inline TPoint Location() const;
	inline void SetLocation(const TPoint& value);
	inline TInt X() const;
	inline void SetX(TInt val);
	inline TInt Y() const;
	inline void SetY(TInt val);
	inline TInt Left() const;
	inline TInt Top() const;
	inline TInt Right() const;
	inline void SetRight(TInt val);
	inline TInt Bottom() const;
	inline void SetBottom(TInt val);
	inline TBool Contains(TInt x, TInt y) const;
	inline TBool Contains(const TRect& rect) const;
	inline TBool Contains(TInt ox, TInt oy, TInt ow, TInt oh) const;
	inline void Inflate(TInt w, TInt h);
	inline void Inflate(const TSize& size);
	inline void Intersect(const TRect& rect);
	inline TBool IntersectsWith(const TRect& rect);
	};

inline TRectEx::TRectEx()
	: TRect()
	{	
	}

inline TRectEx::TRectEx(TInt aAx, TInt aAy, TInt aBx, TInt aBy)
	: TRect(aAx, aAy, aBx, aBy)
	{
	}

inline TRectEx::TRectEx(const TPoint& aPointA, const TPoint& aPointB)
	: TRect(aPointA, aPointB)
	{
	}

inline TRectEx::TRectEx(const TPoint& aPoint, const TSize& aSize)
	: TRect(aPoint, aSize)
	{
	
	}

inline TRectEx::TRectEx(const TSize& aSize)
	: TRect(aSize)
	{
	
	}

inline TRectEx::TRectEx(const TRect& aRect)
	: TRect(aRect.iTl, aRect.iBr)
	{
	
	}

inline TRect TRectEx::FromLTRB(TInt left, TInt top, TInt right, TInt bottom)
	{
	return TRect(left, top, right, bottom);
	}

inline TBool TRectEx::Contains(TInt x, TInt y, TInt left, TInt top, TInt width, TInt height)
	{
	return x >= left && y >= top && x <= left + width && y <= top + height;
	}

inline TRect TRectEx::Inflate(const TRect& rect, TInt x, TInt y)
	{
	TRectEx rectangle(rect);
	rectangle.Inflate(x, y);
	return rectangle;
	}

inline TRect TRectEx::Intersect(TInt ax, TInt ay, TInt aw, TInt ah, TInt bx, TInt by, TInt bw, TInt bh)
	{
	TInt x = Max(ax, bx);
	TInt num2 = Min((TInt) (ax + aw), (TInt) (bx + bw));
	TInt y = Max(ay, by);
	TInt num4 = Min((TInt) (ay + ah), (TInt) (by + bh));
	if ((num2 >= x) && (num4 >= y)) 
		{
		return TRect(x, y, x + num2, y + num4);
		}
	
	return TRect(0, 0, 0, 0);		
	}

inline TRect TRectEx::Intersect(const TRect& a, const TRect& b)
	{
	return Intersect(
			a.iTl.iX
			, a.iTl.iY
			, a.Width()
			, a.Height()
			, b.iTl.iX
			, b.iTl.iY
			, b.Width()
			, b.Height());		
	}

inline TBool TRectEx::IntersectsWith(TInt ax, TInt ay, TInt aw, TInt ah, TInt x, TInt y, TInt w, TInt h)
	{
	return ((((ax < (x + w)) && (x < (ax + aw))) && (ay < (y + h))) && (y < (ay + ah)));
	}

inline TRect TRectEx::Union(const TRect& a, const TRect& b)
	{
	TInt x = Min(a.iTl.iX, b.iTl.iX);
	TInt num2 = Max((TInt) (a.iTl.iX + a.Width()), (TInt) (b.iTl.iX + b.Width()));
	TInt y = Min(a.iTl.iY, b.iTl.iY);
	TInt num4 = Max((TInt) (a.iTl.iY + a.Height()), (TInt) (b.iTl.iY + b.Height()));
	return TRect(x, y, x + num2, y + num4);
	}

inline void TRectEx::Set(const TRect& aRect)
	{
	SetRect(aRect.iTl.iX, aRect.iTl.iY, aRect.iBr.iX, aRect.iBr.iY);
	}

inline TPoint TRectEx::Location() const
	{
	return TPoint(iTl.iX, iTl.iY);
	}

inline void TRectEx::SetLocation(const TPoint& value)
	{
	iTl.iX = value.iX;
	iTl.iY = value.iY;
	}

inline TInt TRectEx::X() const
	{
	return iTl.iX;
	}

inline void TRectEx::SetX(TInt val)
	{
	iTl.iX = val;
	}

inline TInt TRectEx::Y() const
	{
	return iTl.iY;
	}

inline void TRectEx::SetY(TInt val)
	{
	iTl.iY = val;
	}

inline TInt TRectEx::Left() const
	{
	return X();
	}

inline TInt TRectEx::Top() const
	{
	return Y();
	}

inline TInt TRectEx::Right() const
	{
	return iBr.iX; 
	}

inline void TRectEx::SetRight(TInt val)
	{
	iBr.iX = val;
	}

inline TInt TRectEx::Bottom() const
	{
	return iBr.iY;
	}

inline void TRectEx::SetBottom(TInt val)
	{
	iBr.iY = val;
	}

inline TBool TRectEx::Contains(TInt x, TInt y) const
	{
	return Contains(x, y, X(), Y(), Width(), Height());
	}

inline TBool TRectEx::Contains(const TRect& rect) const
	{
	return ((((X() <= rect.iTl.iX) 
		&& ((rect.iTl.iX + rect.Width()) <= (X() + Width()))) 
		&& (Y() <= rect.iTl.iY)) 
		&& ((rect.iTl.iY + rect.Height()) <= (Y() + Height())));
	}

inline TBool TRectEx::Contains(TInt ox, TInt oy, TInt ow, TInt oh) const
	{
	return ((((X() <= ox) 
		&& ((ox + ow) <= (X() + Width()))) 
		&& (Y() <= oy)) 
		&& ((oy + oh) <= (Y() + Height())));	
	}

inline void TRectEx::Inflate(TInt w, TInt h)
	{
	iTl.iX -= w;
	iTl.iY -= h;
	
	SetWidth(Width() + 2 * w);
	SetHeight(Height() + 2 * h);
	}

inline void TRectEx::Inflate(const TSize& size)
	{
	Inflate(size.iWidth, size.iHeight);	
	}

inline void TRectEx::Intersect(const TRect& rect)
	{
	TRect rectangle = Intersect(rect, *this);
	iTl.iX = rectangle.iTl.iX;
	iTl.iY = rectangle.iTl.iY;
	SetWidth(rectangle.Width());
	SetHeight(rectangle.Height());
	
	}

inline TBool TRectEx::IntersectsWith(const TRect& rect)
	{
	return ((((rect.iTl.iX < (X() + Width())) 
		&& (X() < (rect.iTl.iX + rect.Width()))) 
		&& (rect.iTl.iY < (Y() + Height()))) 
		&& (Y() < (rect.iTl.iY + rect.Height())));		
	}

#endif
